package com.zjdiepu.www.security.encode.rsa;  
  
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zjdiepu.www.security.encode.base64.Base64;
  
/**
 * 类描述:RSA对称算法<br/>     
 * 项目名称:zjdiepu-client <br/> 
 * 类名称:RSAEncrypt <br/>     
 * 创建人:xiongxiaotun <br/> 
 * 创建时间:2017年8月16日 下午4:11:36  <br/>   
 * 修改人:xiongxiaotun <br/> 
 * 修改时间: 2017年8月16日 下午4:11:36   <br/>  
 * 修改备注:   <br/> 
 * @version V1.0   <br/>
 */
public class RsaEncrypt { 
	private static final Logger logger = LoggerFactory.getLogger(RsaEncrypt.class);
	
	public static final int KEY_SIZE = 512;
	
	public static void main(String[] args) {
		for(int i = 0; i < 8; i++) {
			System.out.println(UUID.randomUUID().toString().replaceAll("-", ""));
		}
		genKeyPair("d:/rsa/");
	}
	
    /** 
     * 随机生成密钥对 
     */  
    public static void genKeyPair(String filePath) {  
        // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象  
        KeyPairGenerator keyPairGen = null;  
        try {  
            keyPairGen = KeyPairGenerator.getInstance("RSA");  
        } catch (NoSuchAlgorithmException e) {  
        	logger.error("生成秘钥对:filePath:{}.异常栈:{}", filePath, e);
        }  
        // 初始化密钥对生成器，密钥大小为96-1024位  
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());  
        // 生成一个密钥对，保存在keyPair中  
        KeyPair keyPair = keyPairGen.generateKeyPair();  
        // 得到私钥  
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
        // 得到公钥  
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
        try (// 将密钥对写入到文件  
                FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");  
                FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");  
                BufferedWriter pubbw = new BufferedWriter(pubfw);  
                BufferedWriter pribw = new BufferedWriter(prifw);  ){  
            // 得到公钥字符串  
            String publicKeyString = Base64.encode(publicKey.getEncoded());  
            // 得到私钥字符串  
            String privateKeyString = Base64.encode(privateKey.getEncoded());  
            pubbw.write(publicKeyString);  
            pribw.write(privateKeyString);  
            System.out.println("publicKeyString:" + publicKeyString);
            System.out.println("privateKeyString:" + privateKeyString);
        } catch (Exception e) {  
        	logger.error("生成秘钥对:filePath:{}.异常栈:{}", filePath, e);
        }  
    }  
  
    /** 
     * 从文件中输入流中加载公钥 
     *  
     * @param in 
     *            公钥输入流 
     */  
    public static String loadPublicKeyByFile(String path) {  
        try (BufferedReader br = new BufferedReader(new FileReader(path  
                + "/publicKey.keystore")); ){  
            String readLine = null;  
            StringBuilder sb = new StringBuilder();  
            while ((readLine = br.readLine()) != null) {  
                sb.append(readLine);  
            }  
            return sb.toString();  
        } catch (Exception e) {  
        	logger.error("加载公钥:path:{}.异常栈:{}", path, e);
        }
        return null;
    }  
  
    /** 
     * 从字符串中加载公钥 
     *  
     * @param publicKeyStr 
     *            公钥数据字符串 
     * @throws Exception 
     *             加载公钥时产生的异常 
     */  
    public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr){  
        try {  
            byte[] buffer = Base64.decode(publicKeyStr);  
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);  
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);  
        } catch (Exception e) {  
        	logger.error("加载公钥:publicKeyStr:{}.异常栈:{}", publicKeyStr, e);
        }
        return null;
    }  
  
    /** 
     * 从文件中加载私钥 
     *  
     * @param keyFileName 
     *            私钥文件名 
     * @return 是否成功 
     */  
    public static String loadPrivateKeyByFile(String path) {  
        try (BufferedReader br = new BufferedReader(new FileReader(path  
                + "/privateKey.keystore")); ){  
            
            String readLine = null;  
            StringBuilder sb = new StringBuilder();  
            while ((readLine = br.readLine()) != null) {  
                sb.append(readLine);  
            }  
            return sb.toString();  
        } catch (IOException e) {  
        	logger.error("加载私钥 :path:{}.异常栈:{}", path, e);
        }
        return null;
    }  
    
    /**
     * @author xiongxiaotun <br/>
     * @Title loadPrivateKeyByStr  <br/>
     * @Description 从字符串中加载私钥  <br/>
     * @param privateKeyStr
     * @return
     * @throws Exception
     * @version V1.0  <br/>
     */
    public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr){  
        try {  
            byte[] buffer = Base64.decode(privateKeyStr);  
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);  
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
        } catch (Exception e) {  
        	logger.error("加载私钥 :privateKeyStr:{}.异常栈:{}", privateKeyStr, e);
        }
        return null;
    }  
} 